﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Transactions;

using SMA.GENTEv1.Dados;

namespace SMA.GENTEv1
{
    public class ConfiguracaoRegraConvencao
    {
        #region Variaveis Membro
        private int _idConfiguracaoRegraConvencao;
        private Convencao _convencao;
        private TipoBeneficio _beneficio;
        private DateTime _dtFim;
        private DateTime _dtInicio;
        private Status _status;
        private decimal _valor;
        private TipoValor _tipoValor;
        private string _obrigatorio;
        private string _extensivoDependente;
        private List<Cidade> _localidade;
        private string _descontoFolha;
        private GENTEEntities _context;
        #endregion

        #region Parametros
        public int IdConfiguracaoRegraConvencao
        {
            get { return _idConfiguracaoRegraConvencao; }
            set { _idConfiguracaoRegraConvencao = value; }
        }

        public Convencao Convencao
        {
            get { return _convencao; }
            set { _convencao = value; }
        }

        public TipoBeneficio Beneficio
        {
            get { return _beneficio; }
            set { _beneficio = value; }
        }

        public DateTime DtFim
        {
            get { return _dtFim; }
            set { _dtFim = value; }
        }

        public DateTime DtInicio
        {
            get { return _dtInicio; }
            set { _dtInicio = value; }
        }

        public Status Status
        {
            get { return _status; }
            set { _status = value; }
        }

        public decimal Valor
        {
            get { return _valor; }
            set { _valor = value; }
        }

        public TipoValor TipoValor
        {
            get { return _tipoValor; }
            set { _tipoValor = value; }
        }
        

        public string Obrigatorio
        {
            get { return _obrigatorio; }
            set { _obrigatorio = value; }
        }
        
        public string ExtensivoDependente
        {
            get { return _extensivoDependente; }
            set { _extensivoDependente = value; }
        }

        public List<Cidade> Localidade
        {
            get { return _localidade; }
            set { _localidade = value; }
        }

        public string DescontoFolha
        {
            get { return _descontoFolha; }
            set { _descontoFolha = value; }
        }
        #endregion

        #region Construtores
        public ConfiguracaoRegraConvencao()
        {
            try
            {
                _context = new GENTEEntities();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public ConfiguracaoRegraConvencao(int idConfiguracaoRegraConvencao, bool carregaDados)
        {
            try
            {
                _context = new GENTEEntities();
                if (!carregaDados)
                    this._idConfiguracaoRegraConvencao = idConfiguracaoRegraConvencao;
                else
                    Carregar(idConfiguracaoRegraConvencao);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public ConfiguracaoRegraConvencao(int idConfiguracaoRegraConvencao, bool carregaDados, bool carregaLocalidade)
        {
            try
            {
                _context = new GENTEEntities();
                if (!carregaDados)
                    this._idConfiguracaoRegraConvencao = idConfiguracaoRegraConvencao;
                else
                    Carregar(idConfiguracaoRegraConvencao, carregaLocalidade);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Métodos Privados

        #region Métodos Gerais
        private void VerificarCadastro()
        {
            try
            {
                if (this._convencao == null)
                    throw new Exception("É necessário informar a convenção dessa configuração!");

                if (this._convencao.IdConvencaoSindicato == 0)
                    throw new Exception("É necessário informar a convenção dessa configuração!");

                if (this._beneficio == null)
                    throw new Exception("É necessário informar o benefício dessa configuração!");

                if (this._beneficio.IdTipoBeneficio == 0)
                    throw new Exception("É necessário informar o benefício dessa configuração!");

                if (this._status == null)
                    throw new Exception("É necessário informar qual a situação da configuração!");

                if (this._status.IdStatus == 0)
                    throw new Exception("É necessário informar qual a situação da configuração!");

                if (this._dtFim < this._dtInicio)
                    throw new Exception("É necessário informar para o campo Data Final do período de Validade uma data maior daquela que se encontra no campo Data Inicial!");

                if (this._tipoValor == null)
                    throw new Exception("É necessário informar o tipo de valor utilizado pela configuração!");

                if (this._tipoValor.IdTipoValor == 0)
                    throw new Exception("É necessário informar o tipo de valor utilizado pela configuração!");

                if (this._valor == 0)
                {
                    switch (this._tipoValor.IdTipoValor)
                    {
                        case (int)TipoValor.Tipo.Porcentagem:
                            throw new Exception("É necessário informar o valor em porcentagem utilizado pela configuração!");
                        case (int)TipoValor.Tipo.Dinheiro:
                            throw new Exception("É necessário informar o valor em dinheiro utilizado pela configuração!");
                        case (int)TipoValor.Tipo.Unidade:
                            throw new Exception("É necessário informar o valor em unidade utilizado pela configuração!");
                    }
                }

                if (this._obrigatorio == string.Empty)
                    throw new Exception("É necessário informar a obrigatoriedade dessa configuração!");

                if (this._extensivoDependente == string.Empty)
                    throw new Exception("É necessário informar se essa configuração é extendida para os dependentes!");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void EstruturaGradeHistParam(ref DataTable grade)
        {
            try
            {
                DataColumn idConfiguracaoRegraConvencao = new DataColumn();
                idConfiguracaoRegraConvencao.ColumnName = "IdConfiguracaoRegraConvencao";
                idConfiguracaoRegraConvencao.DataType = Type.GetType("System.Int32");
                grade.Columns.Add(idConfiguracaoRegraConvencao);

                DataColumn dtInicio = new DataColumn();
                dtInicio.ColumnName = "DtInicio";
                dtInicio.DataType = Type.GetType("System.DateTime");
                grade.Columns.Add(dtInicio);

                DataColumn dtFim = new DataColumn();
                dtFim.ColumnName = "DtFim";
                dtFim.DataType = Type.GetType("System.DateTime");
                grade.Columns.Add(dtFim);

                DataColumn status = new DataColumn();
                status.ColumnName = "Status";
                status.DataType = Type.GetType("System.String");
                grade.Columns.Add(status);

                DataColumn localidade = new DataColumn();
                localidade.ColumnName = "Localidade";
                localidade.DataType = Type.GetType("System.String");
                grade.Columns.Add(localidade);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Métodos de Seleção
        private void Carregar(int idConfiguracaoRegraConvencao)
        {
            try
            {
                var consulta = (from config in _context.tab_configuracao_regra_convencao
                                where config.id_configuracao_regra_convencao == idConfiguracaoRegraConvencao
                                select new
                                {
                                    config.id_configuracao_regra_convencao,
                                    config.dt_inicio,
                                    config.dt_fim,
                                    config.valor,
                                    config.obrigatorio,
                                    config.extensivo_dependente
                                });

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    this._idConfiguracaoRegraConvencao = list.id_configuracao_regra_convencao;
                    this._dtInicio = list.dt_inicio;
                    this._dtFim = list.dt_fim;
                    this._valor = list.valor;
                    this._obrigatorio = list.obrigatorio;
                    this._extensivoDependente = list.extensivo_dependente;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void Carregar(int idConfiguracaoRegraConvencao, bool carregaLocalidade)
        {
            try
            {
                var consulta = (from config in _context.tab_configuracao_regra_convencao
                                where config.id_configuracao_regra_convencao == idConfiguracaoRegraConvencao
                                select new
                                {
                                    config.id_configuracao_regra_convencao,
                                    config.dt_inicio,
                                    config.dt_fim,
                                    config.valor,
                                    config.obrigatorio,
                                    config.extensivo_dependente
                                });

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    this._idConfiguracaoRegraConvencao = list.id_configuracao_regra_convencao;
                    this._dtInicio = list.dt_inicio;
                    this._dtFim = list.dt_fim;
                    this._valor = list.valor;
                    this._obrigatorio = list.obrigatorio;
                    this._extensivoDependente = list.extensivo_dependente;

                    if (carregaLocalidade)
                        this._localidade = SelectLocalidadesConfig(list.id_configuracao_regra_convencao);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private int RetornaIdConfiguracaoRegraConvencao()
        {
            try
            {
                int resultado = 0;

                var consulta = (from config in _context.tab_configuracao_regra_convencao
                                orderby config.id_configuracao_regra_convencao descending
                                select new
                                {
                                    config.id_configuracao_regra_convencao
                                }).Take(1);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    resultado = list.id_configuracao_regra_convencao;
                }

                return resultado;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private List<Cidade> SelectLocalidadesConfig(int idConfiguracaoRegraConvencao)
        {
            try
            {
                List<Cidade> listCidade = new List<Cidade>();

                var consulta = (from cidade in _context.tab_configuracao_regra_localidade
                                where cidade.tab_configuracao_regra_convencao.id_configuracao_regra_convencao == idConfiguracaoRegraConvencao
                                select new
                                {
                                    cidade.tab_cidade.id_cidade
                                });

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    Cidade cidade = new Cidade(list.id_cidade);

                    listCidade.Add(cidade);
                }

                return listCidade;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Métodos de Persistência
        private void DesativarConfiguracaoAnterior(int idConfiguracaoRegraConvencao, int idBeneficio)
        {
            try
            {
                var consulta = (from config in _context.tab_configuracao_regra_convencao
                                where config.id_configuracao_regra_convencao < idConfiguracaoRegraConvencao
                                && config.tab_tipo_beneficio.id_tipo_beneficio == idBeneficio
                                orderby config.id_configuracao_regra_convencao descending
                                select config).Take(1);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    tab_configuracao_regra_convencao tabConfiguracaoRegraConvencao = (from config in _context.tab_configuracao_regra_convencao
                                                                                      where config.id_configuracao_regra_convencao == list.id_configuracao_regra_convencao
                                                                                      select config).First();

                    tabConfiguracaoRegraConvencao.tab_statusReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_status", "id_status", 2);

                    _context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void SalvarLocalidade(int idConfiguracaoRegraConvencao)
        {
            try
            {
                for (int i = 0; i < this._localidade.Count; i++)
                {
                    tab_configuracao_regra_localidade tabConfigLocalidade = new tab_configuracao_regra_localidade();
                    tabConfigLocalidade.tab_configuracao_regra_convencaoReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_configuracao_regra_convencao", "id_configuracao_regra_convencao", idConfiguracaoRegraConvencao);
                    tabConfigLocalidade.tab_cidadeReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_cidade", "id_cidade", this._localidade[i].IdCidade);

                    _context.AddTotab_configuracao_regra_localidade(tabConfigLocalidade);
                    _context.SaveChanges();
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #endregion

        #region Métodos Públicos

        #region Métodos de Seleção
        public List<ConfiguracaoRegraConvencao> SelectRegraAtual(int idBeneficio, int idConvencao)
        {
            try
            {
                List<ConfiguracaoRegraConvencao> listConfigConvencao = new List<ConfiguracaoRegraConvencao>();

                var consulta = (from config in _context.tab_configuracao_regra_convencao
                                where config.tab_tipo_beneficio.id_tipo_beneficio == idBeneficio
                                && config.tab_sindicato_convencao.id_convencao_sindicato == idConvencao
                                orderby config.id_configuracao_regra_convencao descending
                                select new
                                {
                                    config.id_configuracao_regra_convencao,
                                    config.dt_inicio,
                                    config.dt_fim,
                                    config.valor,
                                    config.obrigatorio,
                                    config.extensivo_dependente,
                                    config.desconto_folha
                                }).Take(1);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    ConfiguracaoRegraConvencao configConvencao = new ConfiguracaoRegraConvencao();
                    configConvencao.IdConfiguracaoRegraConvencao = list.id_configuracao_regra_convencao;
                    configConvencao.DtInicio = list.dt_inicio;
                    configConvencao.DtFim = list.dt_fim;
                    configConvencao.Valor = list.valor;
                    configConvencao.Obrigatorio = list.obrigatorio;
                    configConvencao.ExtensivoDependente = list.extensivo_dependente;
                    configConvencao.DescontoFolha = list.desconto_folha;

                    listConfigConvencao.Add(configConvencao);
                }

                return listConfigConvencao;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<ConfiguracaoRegraConvencao> SelectHistorico(int idBeneficio, int idConvencao)
        {
            try
            {
                List<ConfiguracaoRegraConvencao> listConfigConvencao = new List<ConfiguracaoRegraConvencao>();

                var consulta = (from config in _context.tab_configuracao_regra_convencao
                                where config.tab_tipo_beneficio.id_tipo_beneficio == idBeneficio
                                && config.tab_sindicato_convencao.id_convencao_sindicato == idConvencao
                                orderby config.id_configuracao_regra_convencao descending
                                select new
                                {
                                    config.id_configuracao_regra_convencao,
                                    config.dt_inicio,
                                    config.dt_fim,
                                    config.tab_status.id_status,
                                    config.valor,
                                    config.obrigatorio,
                                    config.extensivo_dependente,
                                    config.desconto_folha
                                });

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    ConfiguracaoRegraConvencao configConvencao = new ConfiguracaoRegraConvencao();
                    configConvencao.IdConfiguracaoRegraConvencao = list.id_configuracao_regra_convencao;
                    configConvencao.DtInicio = list.dt_inicio;
                    configConvencao.DtFim = list.dt_fim;
                    configConvencao.Status = new Status(list.id_status);
                    configConvencao.Valor = list.valor;
                    configConvencao.Obrigatorio = list.obrigatorio;
                    configConvencao.ExtensivoDependente = list.extensivo_dependente;
                    configConvencao.DescontoFolha = list.desconto_folha;

                    listConfigConvencao.Add(configConvencao);
                }

                return listConfigConvencao;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public DataTable SelectHistorico(int idBeneficio, int idConvencao, bool carregaLocalidade)
        {
            try
            {
                DataTable gradeHistParam = new DataTable();

                EstruturaGradeHistParam(ref gradeHistParam);

                var consulta = (from config in _context.tab_configuracao_regra_convencao
                                where config.tab_tipo_beneficio.id_tipo_beneficio == idBeneficio
                                && config.tab_sindicato_convencao.id_convencao_sindicato == idConvencao
                                orderby config.id_configuracao_regra_convencao descending
                                select new
                                {
                                    config.id_configuracao_regra_convencao,
                                    config.dt_inicio,
                                    config.dt_fim,
                                    config.tab_status.id_status,
                                    config.valor
                                });

                var listConsulta = consulta.ToList();

                DataRow registro;
                foreach (var list in listConsulta)
                {
                    ConfiguracaoRegraConvencao configConvencao = new ConfiguracaoRegraConvencao();
                    configConvencao.IdConfiguracaoRegraConvencao = list.id_configuracao_regra_convencao;
                    configConvencao.DtInicio = list.dt_inicio;
                    configConvencao.DtFim = list.dt_fim;
                    configConvencao.Status = new Status(list.id_status);
                    configConvencao.Valor = list.valor;

                    if (carregaLocalidade)
                        configConvencao.Localidade = SelectLocalidadesConfig(list.id_configuracao_regra_convencao);

                    registro = gradeHistParam.NewRow();
                    if (configConvencao.Localidade.Count > 0)
                    {
                        foreach (Cidade local in configConvencao.Localidade)
                        {
                            registro["IdConfiguracaoRegraConvencao"] = configConvencao.IdConfiguracaoRegraConvencao;
                            registro["DtInicio"] = configConvencao.DtInicio;
                            registro["DtFim"] = configConvencao.DtFim;
                            registro["Status"] = configConvencao.Status.Descricao;
                            registro["Localidade"] = local.NomeCidade;
                        }
                    }
                    else
                    {
                        registro["IdConfiguracaoRegraConvencao"] = configConvencao.IdConfiguracaoRegraConvencao;
                        registro["DtInicio"] = configConvencao.DtInicio;
                        registro["DtFim"] = configConvencao.DtFim;
                        registro["Status"] = configConvencao.Status.Descricao;
                    }

                    gradeHistParam.Rows.Add(registro);
                }

                return gradeHistParam;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Métodos de Persistência
        public void Salvar()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    VerificarCadastro();

                    if (this._idConfiguracaoRegraConvencao == 0)
                    {
                        tab_configuracao_regra_convencao tabConfiguracaoRegraConvencao = new tab_configuracao_regra_convencao();

                        tabConfiguracaoRegraConvencao.tab_sindicato_convencaoReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_sindicato_convencao", "id_convencao_sindicato", this._convencao.IdConvencaoSindicato);
                        tabConfiguracaoRegraConvencao.tab_tipo_beneficioReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_tipo_beneficio", "id_tipo_beneficio", this._beneficio.IdTipoBeneficio);
                        tabConfiguracaoRegraConvencao.dt_inicio = this._dtInicio;
                        tabConfiguracaoRegraConvencao.dt_fim = this._dtFim;
                        tabConfiguracaoRegraConvencao.tab_statusReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_status", "id_status", this._status.IdStatus);
                        tabConfiguracaoRegraConvencao.valor = this._valor;
                        tabConfiguracaoRegraConvencao.tab_tipo_valorReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_tipo_valor", "id_tipo_valor", this._tipoValor.IdTipoValor);
                        tabConfiguracaoRegraConvencao.obrigatorio = this._obrigatorio;
                        tabConfiguracaoRegraConvencao.extensivo_dependente = this._extensivoDependente;
                        tabConfiguracaoRegraConvencao.desconto_folha = this._descontoFolha;

                        _context.AddTotab_configuracao_regra_convencao(tabConfiguracaoRegraConvencao);
                        _context.SaveChanges();

                        this._idConfiguracaoRegraConvencao = RetornaIdConfiguracaoRegraConvencao();

                        if (this._localidade != null)
                            SalvarLocalidade(this._idConfiguracaoRegraConvencao);

                        DesativarConfiguracaoAnterior(this._idConfiguracaoRegraConvencao, this._beneficio.IdTipoBeneficio);
                    }
                    else
                    {
                        tab_configuracao_regra_convencao tabConfiguracaoRegraConvencao = (from config in _context.tab_configuracao_regra_convencao
                                                                                          where config.id_configuracao_regra_convencao == this._idConfiguracaoRegraConvencao
                                                                                          select config).First();

                        tabConfiguracaoRegraConvencao.tab_sindicato_convencaoReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_sindicato_convencao", "id_convencao_sindicato", this._convencao.IdConvencaoSindicato);
                        tabConfiguracaoRegraConvencao.tab_tipo_beneficioReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_tipo_beneficio", "id_tipo_beneficio", this._beneficio.IdTipoBeneficio);
                        tabConfiguracaoRegraConvencao.dt_inicio = this._dtInicio;
                        tabConfiguracaoRegraConvencao.dt_fim = this._dtFim;
                        tabConfiguracaoRegraConvencao.tab_statusReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_status", "id_status", this._status.IdStatus);
                        tabConfiguracaoRegraConvencao.valor = this._valor;
                        tabConfiguracaoRegraConvencao.tab_tipo_valorReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_tipo_valor", "id_tipo_valor", this._tipoValor.IdTipoValor);
                        tabConfiguracaoRegraConvencao.obrigatorio = this._obrigatorio;
                        tabConfiguracaoRegraConvencao.extensivo_dependente = this._extensivoDependente;
                        tabConfiguracaoRegraConvencao.desconto_folha = this._descontoFolha;

                        _context.SaveChanges();
                    }

                    scope.Complete();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
        #endregion

        #endregion
    }
}
